//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;

using CommunityServer.Galleries.Components;
using CommunityServer.Components;

namespace CommunityServer.Galleries.Components
{
    /// <summary>
    /// Summary description for TrackBackHandler.
    /// </summary>
    public class TrackBackHandler : IHttpHandler
    {
        public TrackBackHandler() 
        {
        }
	
        public void ProcessRequest(HttpContext context)
        {

            context.Response.ContentType="text/xml" ;
			CSContext cntx = CSContext.Current;
			User user = cntx.User;
            int postId = 0;

            try 
            {
                postId = int.Parse(context.Request.QueryString["postid"]) ;
            }
            catch 
            {
                trackbackResponse (context, 1, "EntryID is invalid or missing" ) ;
            }


            if ( context.Request.HttpMethod == "POST" )
            {
                string title     = safeParam(context,"title") ;
                string excerpt   = safeParam(context,"excerpt") ;
                string url       = safeParam(context,"url");
                string blog_name = safeParam(context,"blog_name") ;

				try
				{
					// is the url valid ?
					if ( url == "" )
					{
						trackbackResponse (context, 1, "no url parameter found, please try harder!") ;
					}
	
					string pageTitle = null;
                
					GalleryPost trackedEntry = GalleryPosts.GetPicture(postId);

					if(trackedEntry == null)
					{
						trackbackResponse (context, 2, "The link does not exist" ) ;
						return;
					}

					Gallery g = trackedEntry.Section as Gallery;

					Permissions.AccessCheck(g,Permission.View, user );

					if(!g.EnableTrackbacksDefault)
					{
						trackbackResponse (context, 2, "Trackbacks are not enabled" ) ;
						return;
					}

					if(!IsNewTrackBack(trackedEntry,url))
					{
						trackbackResponse (context, 2, "Trackbacks already exists" ) ;
						return;
                    
					}
				
					if (!SourceContainsTarget(url,Globals.FullPath(GalleryUrls.Instance().ViewPicture(g.ApplicationKey, trackedEntry) ), out pageTitle))
					{
						trackbackResponse (context, 2, "Sorry couldn't find a relevant link in " + url ) ;
					}

                
					GalleryPost entry = new GalleryPost();
					entry.GalleryPostType = GalleryPostType.Trackback;
					entry.SectionID = g.SectionID;
					entry.ParentID = postId;
					entry.Subject = title;
					entry.TitleUrl = url;
					entry.TrackBackName = blog_name;
					entry.Body = excerpt;
					entry.IsApproved = true;
					entry.PostDate = DateTime.Now;
					entry.UserTime = DateTime.Now;

					entry = GalleryPosts.Add(entry, user);

					// Log success message to EventLog
					string message = String.Format("Trackback request received by Community Server for PostID {0} and successfully saved as PostID {1}.", postId, entry.PostID);
					EventLogs.Info(message, "PhotoGallery", 300, cntx.SettingsID);

				}
				catch (System.Threading.ThreadAbortException) {}
				catch (System.Exception ex)
				{
					if (ex.Message != null)
						trackbackResponse (context, 0, string.Format("Error occurred while processing Trackback: {0}", ex.Message));
					else
						trackbackResponse (context, 0, "Unknown error occurred while processing Trackback.");
				}
            }
            else
            {

                GalleryPost entry = GalleryPosts.GetPicture(postId) ;
                Gallery g = entry.Section as Gallery;

                Permissions.AccessCheck(g,Permission.View, user);

                XmlTextWriter w = new XmlTextWriter(context.Response.Output) ;
                w.Formatting = Formatting.Indented;

                w.WriteStartDocument() ;
                w.WriteStartElement("response") ;
                w.WriteElementString("error", "0") ;
                w.WriteStartElement("rss") ;
                w.WriteAttributeString("version", "0.91") ;
                w.WriteStartElement("channel") ;
                w.WriteElementString("title", entry.Subject ) ;
                w.WriteElementString("link", GalleryUrls.Instance().TrackbackPingUrl(postId));
                w.WriteElementString("description", "" ) ;
                w.WriteElementString("language", "en-us" ) ;

                w.WriteEndElement() ; // channel
                w.WriteEndElement() ; // rss 
                w.WriteEndElement() ; // response
                w.WriteEndDocument() ;
		
            }

        }

        public bool IsReusable
        {
            get { return false; }
        }

        private void trackbackResponse(HttpContext context, int errNum, string errText)
        {
            XmlDocument d = new XmlDocument() ;
            XmlElement root = d.CreateElement("response") ;
            d.AppendChild(root) ;
            XmlElement er = d.CreateElement("error") ;
            root.AppendChild(er) ;
            er.AppendChild(d.CreateTextNode(errNum.ToString())) ;
            if ( errText != "" )
            {
                XmlElement msg = d.CreateElement("message") ;
                root.AppendChild(msg) ;
                msg.AppendChild(d.CreateTextNode(errText)) ;
            }
            d.Save ( context.Response.Output ) ;
            context.Response.End() ;
        }

        private string safeParam(HttpContext context,string pName)
        {
            if ( context.Request.Form[pName] != null )
                return Globals.HtmlEncode(context.Request.Form[pName]);
            return  string.Empty;
        }

        public static  bool SourceContainsTarget(string sURI, string tURI, out string pageTitle)
        {
            pageTitle = string.Empty ;
            string page = CSRequest.GetPageText(sURI,tURI);
            if (page == null ||  page.IndexOf(tURI) < 0 )
                return false ;
						
            string pat = @"<head.*?>.*<title.*?>(.*)</title.*?>.*</head.*?>" ;
            Regex reg = new Regex(pat, RegexOptions.IgnoreCase | RegexOptions.Singleline  ) ;
            Match m = reg.Match(page) ;
            if ( m.Success )
            {
                pageTitle = m.Result("$1") ;
                return true ;
            }
 
            return false ;
        }

        private static bool IsNewTrackBack(GalleryPost post, string trackbackUrl)
        {
            GalleryThreadQuery query = new GalleryThreadQuery();
            query.SectionID = post.SectionID;
            query.IncludeCategories = false;
            query.PostID = post.PostID;
            query.ReturnFullThread = true;
            
            PostSet ps = GalleryPosts.GetPostSet(query)  ;
            ps.Organize();

            foreach(GalleryPost p in ps.Replies)
            {
                if ( (string.Compare(trackbackUrl,p.TitleUrl,true) == 0) && (p.GalleryPostType == GalleryPostType.Trackback) )
                    return false;
            }

            return true;
        }
    }
}

